var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
define(["require", "exports", "vscode-css-languageservice/services/cssCompletion", "vscode-css-languageservice/parser/cssNodes", "vscode-languageserver-types"], function (require, exports, cssCompletion_1, nodes, vscode_languageserver_types_1) {
    /*---------------------------------------------------------------------------------------------
     *  Copyright (c) Microsoft Corporation. All rights reserved.
     *  Licensed under the MIT License. See License.txt in the project root for license information.
     *--------------------------------------------------------------------------------------------*/
    'use strict';
    Object.defineProperty(exports, "__esModule", { value: true });
    var SCSSCompletion = /** @class */ (function (_super) {
        __extends(SCSSCompletion, _super);
        function SCSSCompletion() {
            return _super.call(this, '$') || this;
        }
        SCSSCompletion.prototype.createReplaceFunction = function () {
            var tabStopCounter = 1;
            return function (match, p1) {
                return '\\' + p1 + ': ${' + tabStopCounter++ + ':' + (SCSSCompletion.variableDefaults[p1] || '') + '}';
            };
        };
        SCSSCompletion.prototype.createFunctionProposals = function (proposals, existingNode, sortToEnd, result) {
            for (var _i = 0, proposals_1 = proposals; _i < proposals_1.length; _i++) {
                var p = proposals_1[_i];
                var insertText = p.func.replace(/\[?(\$\w+)\]?/g, this.createReplaceFunction());
                var label = p.func.substr(0, p.func.indexOf('('));
                var item = {
                    label: label,
                    detail: p.func,
                    documentation: p.desc,
                    textEdit: vscode_languageserver_types_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
                    insertTextFormat: vscode_languageserver_types_1.InsertTextFormat.Snippet,
                    kind: vscode_languageserver_types_1.CompletionItemKind.Function
                };
                if (sortToEnd) {
                    item.sortText = 'z';
                }
                result.items.push(item);
            }
            return result;
        };
        SCSSCompletion.prototype.getCompletionsForSelector = function (ruleSet, isNested, result) {
            this.createFunctionProposals(SCSSCompletion.selectorFuncs, void 0, true, result);
            return _super.prototype.getCompletionsForSelector.call(this, ruleSet, isNested, result);
        };
        SCSSCompletion.prototype.getTermProposals = function (entry, existingNode, result) {
            var functions = SCSSCompletion.builtInFuncs;
            if (entry) {
                functions = functions.filter(function (f) { return !f.type || entry.restrictions.indexOf(f.type) !== -1; });
            }
            this.createFunctionProposals(functions, existingNode, true, result);
            return _super.prototype.getTermProposals.call(this, entry, existingNode, result);
        };
        SCSSCompletion.prototype.getColorProposals = function (entry, existingNode, result) {
            this.createFunctionProposals(SCSSCompletion.colorProposals, existingNode, false, result);
            return _super.prototype.getColorProposals.call(this, entry, existingNode, result);
        };
        SCSSCompletion.prototype.getCompletionsForDeclarationProperty = function (declaration, result) {
            this.getCompletionsForSelector(null, true, result);
            return _super.prototype.getCompletionsForDeclarationProperty.call(this, declaration, result);
        };
        SCSSCompletion.prototype.getCompletionsForExtendsReference = function (extendsRef, existingNode, result) {
            var symbols = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Rule);
            for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
                var symbol = symbols_1[_i];
                var suggest = {
                    label: symbol.name,
                    textEdit: vscode_languageserver_types_1.TextEdit.replace(this.getCompletionRange(existingNode), symbol.name),
                    kind: vscode_languageserver_types_1.CompletionItemKind.Function,
                };
                result.items.push(suggest);
            }
            return result;
        };
        SCSSCompletion.variableDefaults = {
            '$red': '1',
            '$green': '2',
            '$blue': '3',
            '$alpha': '1.0',
            '$color': '#000000',
            '$weight': '0.5',
            '$hue': '0',
            '$saturation': '0%',
            '$lightness': '0%',
            '$degrees': '0',
            '$amount': '0',
            '$string': '""',
            '$substring': '"s"',
            '$number': '0',
            '$limit': '1'
        };
        SCSSCompletion.colorProposals = [
            { func: 'red($color)', desc: 'Gets the red component of a color.' },
            { func: 'green($color)', desc: 'Gets the green component of a color.' },
            { func: 'blue($color)', desc: 'Gets the blue component of a color.' },
            { func: 'mix($color, $color, [$weight])', desc: 'Mixes two colors together.' },
            { func: 'hue($color)', desc: 'Gets the hue component of a color.' },
            { func: 'saturation($color)', desc: 'Gets the saturation component of a color.' },
            { func: 'lightness($color)', desc: 'Gets the lightness component of a color.' },
            { func: 'adjust-hue($color, $degrees)', desc: 'Changes the hue of a color.' },
            { func: 'lighten($color, $amount)', desc: 'Makes a color lighter.' },
            { func: 'darken($color, $amount)', desc: 'Makes a color darker.' },
            { func: 'saturate($color, $amount)', desc: 'Makes a color more saturated.' },
            { func: 'desaturate($color, $amount)', desc: 'Makes a color less saturated.' },
            { func: 'grayscale($color)', desc: 'Converts a color to grayscale.' },
            { func: 'complement($color)', desc: 'Returns the complement of a color.' },
            { func: 'invert($color)', desc: 'Returns the inverse of a color.' },
            { func: 'alpha($color)', desc: 'Gets the opacity component of a color.' },
            { func: 'opacity($color)', desc: 'Gets the alpha component (opacity) of a color.' },
            { func: 'rgba($color, $alpha)', desc: 'Changes the alpha component for a color.' },
            { func: 'opacify($color, $amount)', desc: 'Makes a color more opaque.' },
            { func: 'fade-in($color, $amount)', desc: 'Makes a color more opaque.' },
            { func: 'transparentize($color, $amount)', desc: 'Makes a color more transparent.' },
            { func: 'fade-out($color, $amount)', desc: 'Makes a color more transparent.' },
            { func: 'adjust-color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])', desc: 'Increases or decreases one or more components of a color.' },
            { func: 'scale-color($color, [$red], [$green], [$blue], [$saturation], [$lightness], [$alpha])', desc: 'Fluidly scales one or more properties of a color.' },
            { func: 'change-color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha])', desc: 'Changes one or more properties of a color.' },
            { func: 'ie-hex-str($color)', desc: 'Converts a color into the format understood by IE filters.' }
        ];
        SCSSCompletion.selectorFuncs = [
            { func: 'selector-nest($selectors…)', desc: 'Nests selector beneath one another like they would be nested in the stylesheet.' },
            { func: 'selector-append($selectors…)', desc: 'Appends selectors to one another without spaces in between.' },
            { func: 'selector-extend($selector, $extendee, $extender)', desc: 'Extends $extendee with $extender within $selector.' },
            { func: 'selector-replace($selector, $original, $replacement)', desc: 'Replaces $original with $replacement within $selector.' },
            { func: 'selector-unify($selector1, $selector2)', desc: 'Unifies two selectors to produce a selector that matches elements matched by both.' },
            { func: 'is-superselector($super, $sub)', desc: 'Returns whether $super matches all the elements $sub does, and possibly more.' },
            { func: 'simple-selectors($selector)', desc: 'Returns the simple selectors that comprise a compound selector.' },
            { func: 'selector-parse($selector)', desc: 'Parses a selector into the format returned by &.' }
        ];
        SCSSCompletion.builtInFuncs = [
            { func: 'unquote($string)', desc: 'Removes quotes from a string.' },
            { func: 'quote($string)', desc: 'Adds quotes to a string.' },
            { func: 'str-length($string)', desc: 'Returns the number of characters in a string.' },
            { func: 'str-insert($string, $insert, $index)', desc: 'Inserts $insert into $string at $index.' },
            { func: 'str-index($string, $substring)', desc: 'Returns the index of the first occurance of $substring in $string.' },
            { func: 'str-slice($string, $start-at, [$end-at])', desc: 'Extracts a substring from $string.' },
            { func: 'to-upper-case($string)', desc: 'Converts a string to upper case.' },
            { func: 'to-lower-case($string)', desc: 'Converts a string to lower case.' },
            { func: 'percentage($number)', desc: 'Converts a unitless number to a percentage.', type: 'percentage' },
            { func: 'round($number)', desc: 'Rounds a number to the nearest whole number.' },
            { func: 'ceil($number)', desc: 'Rounds a number up to the next whole number.' },
            { func: 'floor($number)', desc: 'Rounds a number down to the previous whole number.' },
            { func: 'abs($number)', desc: 'Returns the absolute value of a number.' },
            { func: 'min($numbers)', desc: 'Finds the minimum of several numbers.' },
            { func: 'max($numbers)', desc: 'Finds the maximum of several numbers.' },
            { func: 'random([$limit])', desc: 'Returns a random number.' },
            { func: 'length($list)', desc: 'Returns the length of a list.' },
            { func: 'nth($list, $n)', desc: 'Returns a specific item in a list.' },
            { func: 'set-nth($list, $n, $value)', desc: 'Replaces the nth item in a list.' },
            { func: 'join($list1, $list2, [$separator])', desc: 'Joins together two lists into one.' },
            { func: 'append($list1, $val, [$separator])', desc: 'Appends a single value onto the end of a list.' },
            { func: 'zip($lists)', desc: 'Combines several lists into a single multidimensional list.' },
            { func: 'index($list, $value)', desc: 'Returns the position of a value within a list.' },
            { func: 'list-separator(#list)', desc: 'Returns the separator of a list.' },
            { func: 'map-get($map, $key)', desc: 'Returns the value in a map associated with a given key.' },
            { func: 'map-merge($map1, $map2)', desc: 'Merges two maps together into a new map.' },
            { func: 'map-remove($map, $keys)', desc: 'Returns a new map with keys removed.' },
            { func: 'map-keys($map)', desc: 'Returns a list of all keys in a map.' },
            { func: 'map-values($map)', desc: 'Returns a list of all values in a map.' },
            { func: 'map-has-key($map, $key)', desc: 'Returns whether a map has a value associated with a given key.' },
            { func: 'keywords($args)', desc: 'Returns the keywords passed to a function that takes variable arguments.' },
            { func: 'feature-exists($feature)', desc: 'Returns whether a feature exists in the current Sass runtime.' },
            { func: 'variable-exists($name)', desc: 'Returns whether a variable with the given name exists in the current scope.' },
            { func: 'global-variable-exists($name)', desc: 'Returns whether a variable with the given name exists in the global scope.' },
            { func: 'function-exists($name)', desc: 'Returns whether a function with the given name exists.' },
            { func: 'mixin-exists($name)', desc: 'Returns whether a mixin with the given name exists.' },
            { func: 'inspect($value)', desc: 'Returns the string representation of a value as it would be represented in Sass.' },
            { func: 'type-of($value)', desc: 'Returns the type of a value.' },
            { func: 'unit($number)', desc: 'Returns the unit(s) associated with a number.' },
            { func: 'unitless($number)', desc: 'Returns whether a number has units.' },
            { func: 'comparable($number1, $number2)', desc: 'Returns whether two numbers can be added, subtracted, or compared.' },
            { func: 'call($name, $args…)', desc: 'Dynamically calls a Sass function.' }
        ];
        return SCSSCompletion;
    }(cssCompletion_1.CSSCompletion));
    exports.SCSSCompletion = SCSSCompletion;
});
